package cn.slipi.admin.common.handler.logback;

import ch.qos.logback.classic.spi.IThrowableProxy;
import ch.qos.logback.classic.spi.LoggingEvent;
import ch.qos.logback.classic.spi.StackTraceElementProxy;
import ch.qos.logback.core.rolling.RollingFileAppender;

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @author lee
 */
public class EARollingFileAppender<E> extends RollingFileAppender<E> {

    private static LRULinkedHashMap lruCache = new LRULinkedHashMap(1024);

    public EARollingFileAppender() {
        System.out.println(" ---> EARollingFileAppender Initialized -- ");
    }

    @Override
    protected void append(E eventObject) {
        super.append(eventObject);
        if (eventObject instanceof LoggingEvent) {
            LoggingEvent loggingEvent = (LoggingEvent) eventObject;
            this.processExceptionReport(loggingEvent);
        }
    }

    private void processExceptionReport(LoggingEvent loggingEvent) {
        try {
            IThrowableProxy throwableProxy = loggingEvent.getThrowableProxy();
            if (null != throwableProxy) {
                ExceptionReport exceptionReport = new ExceptionReport(throwableProxy);
                Map<ExceptionReport, Integer> exceptionReportMap = (Map) lruCache.get(exceptionReport.exceptionName);
                if (null == exceptionReportMap) {
                    exceptionReportMap = new HashMap();
                    lruCache.put(exceptionReport.exceptionName, exceptionReportMap);
                }

                Integer num = (Integer) ((Map) exceptionReportMap).get(exceptionReport);
                ((Map) exceptionReportMap).put(exceptionReport, null == num ? 1 : num + 1);
            }
        } catch (Exception var6) {
            var6.printStackTrace(System.out);
        }

    }

    public static class ExceptionReport {
        public String exceptionName;
        public String exceptionThrowLine = "";
        public String exceptionThrowClass = "";

        public ExceptionReport(IThrowableProxy throwableProxy) {
            String exceptionClassName = throwableProxy.getClassName();
            this.exceptionName = exceptionClassName.substring(exceptionClassName.lastIndexOf(".") + 1);
            StackTraceElementProxy[] stackTraceElementProxy = throwableProxy.getStackTraceElementProxyArray();
            if (null != stackTraceElementProxy) {
                StackTraceElementProxy topStace = stackTraceElementProxy[0];
                this.exceptionThrowLine = topStace.getSTEAsString().substring(topStace.getSTEAsString().indexOf("(") + 1, topStace.getSTEAsString().length() - 1);
                this.exceptionThrowClass = this.exceptionThrowLine.split(":")[0];
            }

        }

        @Override
        public int hashCode() {
            int result = 1;
            result = 31 * result + (this.exceptionName == null ? 0 : this.exceptionName.hashCode());
            result = 31 * result + (this.exceptionThrowLine == null ? 0 : this.exceptionThrowLine.hashCode());
            return result;
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            } else if (obj == null) {
                return false;
            } else if (this.getClass() != obj.getClass()) {
                return false;
            } else {
                ExceptionReport other = (ExceptionReport) obj;
                if (this.exceptionName == null) {
                    if (other.exceptionName != null) {
                        return false;
                    }
                } else if (!this.exceptionName.equals(other.exceptionName)) {
                    return false;
                }

                if (this.exceptionThrowLine == null) {
                    if (other.exceptionThrowLine != null) {
                        return false;
                    }
                } else if (!this.exceptionThrowLine.equals(other.exceptionThrowLine)) {
                    return false;
                }

                return true;
            }
        }
    }

    public static class LRULinkedHashMap<K, V> extends LinkedHashMap<K, V> {
        private int capacity;
        private static final long serialVersionUID = 1L;

        LRULinkedHashMap(int capacity) {
            super(16, 0.75F, true);
            this.capacity = capacity;
        }

        @Override
        public boolean removeEldestEntry(Map.Entry<K, V> eldest) {
            return this.size() > this.capacity;
        }
    }
}
